mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-07-01 21:39:15 +02:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
b78a533080 | |||
4381888ffd | |||
70f0e8982b | |||
d4cceb0859 | |||
36220dbc9c | |||
6564c61b00 | |||
f1e9983a58 | |||
5d6970c7ee | |||
21b258809d | |||
da763e7700 | |||
956e02404f |
@ -1,4 +1,4 @@
|
||||
version: 10.3.{build}
|
||||
version: 10.4.{build}
|
||||
|
||||
configuration:
|
||||
- Release
|
||||
|
30
.github/workflows/osx.yml
vendored
30
.github/workflows/osx.yml
vendored
@ -6,8 +6,8 @@ on:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: GPXSee
|
||||
qt5:
|
||||
name: GPXSee Qt5 build
|
||||
runs-on: macos-10.15
|
||||
steps:
|
||||
- name: Set environment variables
|
||||
@ -27,5 +27,29 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: GPXSee.dmg
|
||||
name: GPXSee-qt5.dmg
|
||||
path: GPXSee.dmg
|
||||
|
||||
qt6:
|
||||
name: GPXSee Qt6 build
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Set environment variables
|
||||
run: echo "PATH=/usr/local/opt/qt@6/bin:$PATH" >> $GITHUB_ENV
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Install dependencies
|
||||
run: brew install qt6
|
||||
- name: Create localization
|
||||
run: lrelease gpxsee.pro
|
||||
- name: Configure build
|
||||
run: qmake gpxsee.pro
|
||||
- name: Build project
|
||||
run: make -j3
|
||||
- name: Create DMG
|
||||
run: macdeployqt GPXSee.app -dmg
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: GPXSee-qt6.dmg
|
||||
path: GPXSee.dmg
|
||||
|
@ -3,7 +3,7 @@ unix:!macx {
|
||||
} else {
|
||||
TARGET = GPXSee
|
||||
}
|
||||
VERSION = 10.3
|
||||
VERSION = 10.4
|
||||
|
||||
QT += core \
|
||||
gui \
|
||||
|
2365
lang/gpxsee_ko.ts
2365
lang/gpxsee_ko.ts
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,7 @@ Unicode true
|
||||
; The name of the installer
|
||||
Name "GPXSee"
|
||||
; Program version
|
||||
!define VERSION "10.3"
|
||||
!define VERSION "10.4"
|
||||
|
||||
; The file to write
|
||||
OutFile "GPXSee-${VERSION}_x64.exe"
|
||||
|
@ -700,8 +700,8 @@ void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
|
||||
PlotFlags flags)
|
||||
{
|
||||
QRect orig, adj;
|
||||
qreal ratio, diff, q;
|
||||
QPointF origScene, origPos;
|
||||
qreal ratio, diff, q, p;
|
||||
QPointF scenePos, scalePos, posPos, motionPos;
|
||||
int zoom;
|
||||
|
||||
|
||||
@ -712,7 +712,9 @@ void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
|
||||
|
||||
// Compute sizes & ratios
|
||||
orig = viewport()->rect();
|
||||
origPos = _mapScale->pos();
|
||||
scalePos = _mapScale->pos();
|
||||
posPos = _positionCoordinates->pos();
|
||||
motionPos = _motionInfo->pos();
|
||||
|
||||
if (orig.height() * (target.width() / target.height()) - orig.width() < 0) {
|
||||
ratio = target.height() / target.width();
|
||||
@ -737,7 +739,7 @@ void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
|
||||
if (flags & HiRes) {
|
||||
zoom = _map->zoom();
|
||||
QRectF vr(mapToScene(orig).boundingRect());
|
||||
origScene = vr.center();
|
||||
scenePos = vr.center();
|
||||
|
||||
QPointF s(painter->device()->logicalDpiX()
|
||||
/ (qreal)metric(QPaintDevice::PdmDpiX),
|
||||
@ -751,16 +753,22 @@ void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
|
||||
centerOn(center);
|
||||
adj.moveCenter(mapFromScene(center));
|
||||
|
||||
_mapScale->setDigitalZoom(_digitalZoom - log2(s.x() / q));
|
||||
_mapScale->setPos(mapToScene(QPoint(adj.bottomRight() + QPoint(
|
||||
-(SCALE_OFFSET + _mapScale->boundingRect().width()) * (s.x() / q),
|
||||
-(SCALE_OFFSET + _mapScale->boundingRect().height()) * (s.x() / q)))));
|
||||
} else {
|
||||
_mapScale->setDigitalZoom(_digitalZoom - log2(1.0 / q));
|
||||
_mapScale->setPos(mapToScene(QPoint(adj.bottomRight() + QPoint(
|
||||
-(SCALE_OFFSET + _mapScale->boundingRect().width()) / q ,
|
||||
-(SCALE_OFFSET + _mapScale->boundingRect().height()) / q))));
|
||||
}
|
||||
p = s.x() / q;
|
||||
} else
|
||||
p = 1 / q;
|
||||
|
||||
_mapScale->setDigitalZoom(_digitalZoom - log2(p));
|
||||
_mapScale->setPos(mapToScene(adj.bottomRight() + QPoint(
|
||||
-(SCALE_OFFSET + _mapScale->boundingRect().width()) * p,
|
||||
-(SCALE_OFFSET + _mapScale->boundingRect().height()) * p)));
|
||||
_positionCoordinates->setDigitalZoom(_digitalZoom - log2(p));
|
||||
_positionCoordinates->setPos(mapToScene(adj.topLeft() + QPoint(
|
||||
COORDINATES_OFFSET * p,
|
||||
(COORDINATES_OFFSET + _positionCoordinates->boundingRect().height()) * p)));
|
||||
_motionInfo->setDigitalZoom(_digitalZoom - log2(p));
|
||||
_motionInfo->setPos(mapToScene(adj.topRight() + QPoint(
|
||||
(-COORDINATES_OFFSET - _motionInfo->boundingRect().width()) * p,
|
||||
(COORDINATES_OFFSET + _motionInfo->boundingRect().height()) * p)));
|
||||
|
||||
// Print the view
|
||||
render(painter, target, adj);
|
||||
@ -769,10 +777,14 @@ void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
|
||||
if (flags & HiRes) {
|
||||
_map->setZoom(zoom);
|
||||
rescale();
|
||||
centerOn(origScene);
|
||||
centerOn(scenePos);
|
||||
}
|
||||
_mapScale->setDigitalZoom(_digitalZoom);
|
||||
_mapScale->setPos(origPos);
|
||||
_mapScale->setPos(scalePos);
|
||||
_positionCoordinates->setDigitalZoom(_digitalZoom);
|
||||
_positionCoordinates->setPos(posPos);
|
||||
_motionInfo->setDigitalZoom(_digitalZoom);
|
||||
_motionInfo->setPos(motionPos);
|
||||
|
||||
// Exit plot mode
|
||||
_map->setDevicePixelRatio(_deviceRatio, _mapRatio);
|
||||
@ -1111,33 +1123,35 @@ void MapView::drawBackground(QPainter *painter, const QRectF &rect)
|
||||
|
||||
void MapView::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QPointF scaleScenePos = mapToScene(rect().bottomRight() + QPoint(
|
||||
-(SCALE_OFFSET + _mapScale->boundingRect().width()),
|
||||
-(SCALE_OFFSET + _mapScale->boundingRect().height())));
|
||||
if (_mapScale->pos() != scaleScenePos && !_plot)
|
||||
_mapScale->setPos(scaleScenePos);
|
||||
if (!_plot) {
|
||||
QPointF scaleScenePos = mapToScene(rect().bottomRight() + QPoint(
|
||||
-(SCALE_OFFSET + _mapScale->boundingRect().width()),
|
||||
-(SCALE_OFFSET + _mapScale->boundingRect().height())));
|
||||
if (_mapScale->pos() != scaleScenePos)
|
||||
_mapScale->setPos(scaleScenePos);
|
||||
|
||||
if (_cursorCoordinates->isVisible()) {
|
||||
QPointF coordinatesScenePos = mapToScene(rect().bottomLeft()
|
||||
+ QPoint(COORDINATES_OFFSET, -COORDINATES_OFFSET));
|
||||
if (_cursorCoordinates->pos() != coordinatesScenePos && !_plot)
|
||||
_cursorCoordinates->setPos(coordinatesScenePos);
|
||||
}
|
||||
if (_cursorCoordinates->isVisible()) {
|
||||
QPointF coordinatesScenePos = mapToScene(rect().bottomLeft()
|
||||
+ QPoint(COORDINATES_OFFSET, -COORDINATES_OFFSET));
|
||||
if (_cursorCoordinates->pos() != coordinatesScenePos)
|
||||
_cursorCoordinates->setPos(coordinatesScenePos);
|
||||
}
|
||||
|
||||
if (_positionCoordinates->isVisible()) {
|
||||
QPointF coordinatesScenePos = mapToScene(rect().topLeft()
|
||||
+ QPoint(COORDINATES_OFFSET, COORDINATES_OFFSET
|
||||
+ _positionCoordinates->boundingRect().height()));
|
||||
if (_positionCoordinates->pos() != coordinatesScenePos)
|
||||
_positionCoordinates->setPos(coordinatesScenePos);
|
||||
}
|
||||
if (_positionCoordinates->isVisible()) {
|
||||
QPointF coordinatesScenePos = mapToScene(rect().topLeft()
|
||||
+ QPoint(COORDINATES_OFFSET, COORDINATES_OFFSET
|
||||
+ _positionCoordinates->boundingRect().height()));
|
||||
if (_positionCoordinates->pos() != coordinatesScenePos)
|
||||
_positionCoordinates->setPos(coordinatesScenePos);
|
||||
}
|
||||
|
||||
if (_motionInfo->isVisible()) {
|
||||
QPointF coordinatesScenePos = mapToScene(rect().topRight()
|
||||
+ QPoint(-COORDINATES_OFFSET - _motionInfo->boundingRect().width(),
|
||||
COORDINATES_OFFSET + _motionInfo->boundingRect().height()));
|
||||
if (_motionInfo->pos() != coordinatesScenePos)
|
||||
_motionInfo->setPos(coordinatesScenePos);
|
||||
if (_motionInfo->isVisible()) {
|
||||
QPointF coordinatesScenePos = mapToScene(rect().topRight()
|
||||
+ QPoint(-COORDINATES_OFFSET - _motionInfo->boundingRect().width(),
|
||||
COORDINATES_OFFSET + _motionInfo->boundingRect().height()));
|
||||
if (_motionInfo->pos() != coordinatesScenePos)
|
||||
_motionInfo->setPos(coordinatesScenePos);
|
||||
}
|
||||
}
|
||||
|
||||
QGraphicsView::paintEvent(event);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "bitstream.h"
|
||||
|
||||
using namespace Garmin;
|
||||
using namespace IMG;
|
||||
|
||||
bool BitStream1::flush()
|
||||
@ -22,7 +23,7 @@ bool BitStream1::readUInt24(quint32 &val)
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (!read(8, b))
|
||||
return false;
|
||||
val |= (b << (i * 8));
|
||||
val |= (b << (i << 3));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -43,22 +44,22 @@ bool BitStream4F::flush()
|
||||
|
||||
bool BitStream4F::read(quint32 bits, quint32 &val)
|
||||
{
|
||||
if (bits <= 32 - (_used + _unused)) {
|
||||
val = bits ? (_data << _used) >> (32 - bits) : 0;
|
||||
if (bits <= available()) {
|
||||
val = bits ? (_data << _used) >> (32U - bits) : 0;
|
||||
_used += bits;
|
||||
return true;
|
||||
}
|
||||
|
||||
Q_ASSERT(_length && !_unused);
|
||||
quint32 old = (_used < 32) ? (_data << _used) >> (32 - bits) : 0;
|
||||
quint32 old = (_used < 32U) ? (_data << _used) >> (32U - bits) : 0;
|
||||
quint32 bytes = qMin(_length, 4U);
|
||||
|
||||
if (!_file.readVUInt32SW(_hdl, bytes, _data))
|
||||
return false;
|
||||
|
||||
_used -= 32 - bits;
|
||||
_used -= 32U - bits;
|
||||
_length -= bytes;
|
||||
_unused = (4 - bytes) * 8;
|
||||
_unused = (4U - bytes) << 3;
|
||||
_data <<= _unused;
|
||||
|
||||
val = _data >> (32 - _used) | old;
|
||||
@ -74,31 +75,35 @@ BitStream4R::BitStream4R(const SubFile &file, SubFile::Handle &hdl,
|
||||
|
||||
bool BitStream4R::readBytes(quint32 bytes, quint32 &val)
|
||||
{
|
||||
quint32 bits = _used % 8;
|
||||
quint32 b;
|
||||
|
||||
if (bits) {
|
||||
if (!read(8 - bits, b))
|
||||
return false;
|
||||
Q_ASSERT(!b);
|
||||
}
|
||||
|
||||
val = 0;
|
||||
for (quint32 i = 0; i < bytes; i++) {
|
||||
if (!read(8, b))
|
||||
return false;
|
||||
val |= (b << (i * 8));
|
||||
val |= (b << (i << 3));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BitStream4R::readBytesAligned(quint32 bytes, quint32 &val)
|
||||
{
|
||||
quint32 bits = _used & 7U;
|
||||
quint32 b;
|
||||
|
||||
if (bits && !read(8U - bits, b))
|
||||
return false;
|
||||
|
||||
return readBytes(bytes, val);
|
||||
}
|
||||
|
||||
bool BitStream4R::readVUInt32(quint32 &val)
|
||||
{
|
||||
quint32 b;
|
||||
quint8 bytes, shift;
|
||||
|
||||
if (!readBytes(1, b))
|
||||
if (!readBytesAligned(1, b))
|
||||
return false;
|
||||
|
||||
if ((b & 1) == 0) {
|
||||
@ -125,11 +130,11 @@ bool BitStream4R::readVUInt32(quint32 &val)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BitStream4R::readVuint32SM(quint32 &val1, quint32 &val2, quint32 &val2Bits)
|
||||
bool BitStream4R::readVUint32SM(quint32 &val1, quint32 &val2, quint32 &val2Bits)
|
||||
{
|
||||
quint32 b, eb;
|
||||
|
||||
if (!readBytes(1, b))
|
||||
if (!readBytesAligned(1, b))
|
||||
return false;
|
||||
|
||||
if (!(b & 1)) {
|
||||
@ -154,15 +159,16 @@ bool BitStream4R::readVuint32SM(quint32 &val1, quint32 &val2, quint32 &val2Bits)
|
||||
|
||||
bool BitStream4R::skip(quint32 bytes)
|
||||
{
|
||||
if (bytes * 8 > bitsAvailable())
|
||||
return false;
|
||||
quint32 ab = available() >> 3;
|
||||
|
||||
quint32 ab = (32 - (_used + _unused))/8;
|
||||
if (bytes <= ab)
|
||||
_used += bytes * 8;
|
||||
_used += bytes << 3;
|
||||
else {
|
||||
quint32 seek = ((bytes - ab)/4)*4;
|
||||
quint32 read = (bytes - ab)%4;
|
||||
if (bytes > ab + _length)
|
||||
return false;
|
||||
|
||||
quint32 seek = (bytes - ab) & 0xFFFFFFFC;
|
||||
quint32 read = (bytes - ab) & 3U;
|
||||
if (seek && !_file.seek(_hdl, _file.pos(_hdl) - seek))
|
||||
return false;
|
||||
_length -= seek;
|
||||
@ -170,13 +176,13 @@ bool BitStream4R::skip(quint32 bytes)
|
||||
quint32 rb = qMin(_length, 4U);
|
||||
if (!_file.readUInt32(_hdl, _data))
|
||||
return false;
|
||||
if (!_file.seek(_hdl, _file.pos(_hdl) - 8))
|
||||
if (!_file.seek(_hdl, _file.pos(_hdl) - 8U))
|
||||
return false;
|
||||
_length -= rb;
|
||||
_unused = (4 - rb) * 8;
|
||||
_used = read * 8;
|
||||
_unused = (4U - rb) << 3;
|
||||
_used = read << 3;
|
||||
} else
|
||||
_used = 32;
|
||||
_used = 32U;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -184,13 +190,13 @@ bool BitStream4R::skip(quint32 bytes)
|
||||
|
||||
void BitStream4R::resize(quint32 bytes)
|
||||
{
|
||||
quint32 ab = (32 - (_used + _unused) + 7)/8;
|
||||
quint32 ab = bs(available());
|
||||
|
||||
if (ab <= bytes)
|
||||
_length = bytes - ab;
|
||||
else {
|
||||
_length = 0;
|
||||
_unused += (ab - bytes) * 8;
|
||||
_unused += (ab - bytes) << 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,9 +30,11 @@ public:
|
||||
_data(0) {}
|
||||
|
||||
quint64 bitsAvailable() const
|
||||
{return (quint64)_length * 8 + (32 - _used) - _unused;}
|
||||
{return ((quint64)_length << 3) + available();}
|
||||
|
||||
protected:
|
||||
quint32 available() const {return 32U - (_used + _unused);}
|
||||
|
||||
const SubFile &_file;
|
||||
SubFile::Handle &_hdl;
|
||||
quint32 _length, _used, _unused;
|
||||
@ -61,14 +63,17 @@ public:
|
||||
BitStream4R(const SubFile &file, SubFile::Handle &hdl, quint32 length);
|
||||
|
||||
template<typename T> bool read(quint32 bits, T &val);
|
||||
bool readBytes(quint32 bytes, quint32 &val);
|
||||
bool readVUInt32(quint32 &val);
|
||||
bool readVuint32SM(quint32 &val1, quint32 &val2, quint32 &val2Bits);
|
||||
bool readVUint32SM(quint32 &val1, quint32 &val2, quint32 &val2Bits);
|
||||
|
||||
bool skip(quint32 bytes);
|
||||
void resize(quint32 bytes);
|
||||
void save(State &state);
|
||||
bool restore(const State &state);
|
||||
|
||||
private:
|
||||
bool readBytes(quint32 bytes, quint32 &val);
|
||||
bool readBytesAligned(quint32 bytes, quint32 &val);
|
||||
};
|
||||
|
||||
|
||||
@ -105,26 +110,26 @@ bool BitStream1::read(quint32 bits, T &val)
|
||||
template<typename T>
|
||||
bool BitStream4R::read(quint32 bits, T &val)
|
||||
{
|
||||
if (bits <= 32 - (_used + _unused)) {
|
||||
val = bits ? (_data << _used) >> (32 - bits) : 0;
|
||||
if (bits <= available()) {
|
||||
val = bits ? (_data << _used) >> (32U - bits) : 0;
|
||||
_used += bits;
|
||||
return true;
|
||||
}
|
||||
|
||||
Q_ASSERT(_length && !_unused);
|
||||
quint32 old = (_used < 32) ? (_data << _used) >> (32 - bits) : 0;
|
||||
quint32 old = (_used < 32U) ? (_data << _used) >> (32U - bits) : 0;
|
||||
quint32 bytes = qMin(_length, 4U);
|
||||
|
||||
if (!_file.readUInt32(_hdl, _data))
|
||||
return false;
|
||||
if (!_file.seek(_hdl, _file.pos(_hdl) - 8))
|
||||
if (!_file.seek(_hdl, _file.pos(_hdl) - 8U))
|
||||
return false;
|
||||
|
||||
_length -= bytes;
|
||||
_used -= 32 - bits;
|
||||
_unused = (4 - bytes) * 8;
|
||||
_used -= 32U - bits;
|
||||
_unused = (4U - bytes) << 3;
|
||||
|
||||
val = _data >> (32 - _used) | old;
|
||||
val = _data >> (32U - _used) | old;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ template <class BitStream>
|
||||
bool HuffmanStream<BitStream>::fetchData()
|
||||
{
|
||||
quint32 next;
|
||||
quint8 nextSize = qMin((quint64)(32 - _symbolDataSize), _bs.bitsAvailable());
|
||||
quint32 nextSize = qMin((quint64)(32 - _symbolDataSize), _bs.bitsAvailable());
|
||||
|
||||
if (!_bs.read(nextSize, next))
|
||||
return false;
|
||||
|
@ -137,8 +137,51 @@ void LBLFile::clear()
|
||||
_rasters = 0;
|
||||
}
|
||||
|
||||
Label LBLFile::label6b(Handle &hdl, quint32 offset, bool capitalize,
|
||||
Label LBLFile::str2label(const QVector<quint8> &str, bool capitalize,
|
||||
bool convert) const
|
||||
{
|
||||
Shield::Type shieldType = Shield::None;
|
||||
QByteArray label, shieldLabel;
|
||||
QByteArray *bap = &label;
|
||||
int split = -1;
|
||||
|
||||
for (int i = 0; i < str.size(); i++) {
|
||||
const quint8 &c = str.at(i);
|
||||
|
||||
if (c == 0 || c == 0x1d || c == 0x07)
|
||||
break;
|
||||
|
||||
if (c == 0x1c)
|
||||
capitalize = false;
|
||||
else if ((c >= 0x1e && c <= 0x1f)) {
|
||||
if (bap == &shieldLabel)
|
||||
bap = &label;
|
||||
else {
|
||||
if (!bap->isEmpty())
|
||||
bap->append('\n');
|
||||
if (c == 0x1f && split < 0)
|
||||
split = bap->size();
|
||||
}
|
||||
} else if (c < 0x07) {
|
||||
shieldType = static_cast<Shield::Type>(c);
|
||||
bap = &shieldLabel;
|
||||
} else if (bap == &shieldLabel && c == 0x20) {
|
||||
bap = &label;
|
||||
} else
|
||||
bap->append(c);
|
||||
}
|
||||
|
||||
if (split >= 0)
|
||||
label = label.left(split) + ft2m(label.mid(split));
|
||||
else if (convert)
|
||||
label = ft2m(label);
|
||||
QString text(_codec.toString(label));
|
||||
return Label(capitalize && isAllUpperCase(text) ? capitalized(text) : text,
|
||||
Shield(shieldType, _codec.toString(shieldLabel)));
|
||||
}
|
||||
|
||||
Label LBLFile::label6b(const SubFile *file, Handle &fileHdl, quint32 size,
|
||||
bool capitalize, bool convert) const
|
||||
{
|
||||
Shield::Type shieldType = Shield::None;
|
||||
QByteArray label, shieldLabel;
|
||||
@ -147,11 +190,9 @@ Label LBLFile::label6b(Handle &hdl, quint32 offset, bool capitalize,
|
||||
quint8 b1, b2, b3;
|
||||
int split = -1;
|
||||
|
||||
if (!seek(hdl, offset))
|
||||
return Label();
|
||||
|
||||
while (true) {
|
||||
if (!(readByte(hdl, &b1) && readByte(hdl, &b2) && readByte(hdl, &b3)))
|
||||
for (quint32 i = 0; i < size; i = i + 3) {
|
||||
if (!(file->readByte(fileHdl, &b1) && file->readByte(fileHdl, &b2)
|
||||
&& file->readByte(fileHdl, &b3)))
|
||||
return Label();
|
||||
|
||||
int c[]= {b1>>2, (b1&0x3)<<4|b2>>4, (b2&0xF)<<2|b3>>6, b3&0x3F};
|
||||
@ -201,78 +242,33 @@ Label LBLFile::label6b(Handle &hdl, quint32 offset, bool capitalize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Label();
|
||||
}
|
||||
|
||||
Label LBLFile::str2label(const QVector<quint8> &str, bool capitalize,
|
||||
bool convert) const
|
||||
{
|
||||
Shield::Type shieldType = Shield::None;
|
||||
QByteArray label, shieldLabel;
|
||||
QByteArray *bap = &label;
|
||||
int split = -1;
|
||||
|
||||
for (int i = 0; i < str.size(); i++) {
|
||||
const quint8 &c = str.at(i);
|
||||
|
||||
if (c == 0 || c == 0x1d || c == 0x07)
|
||||
break;
|
||||
|
||||
if (c == 0x1c)
|
||||
capitalize = false;
|
||||
else if ((c >= 0x1e && c <= 0x1f)) {
|
||||
if (bap == &shieldLabel)
|
||||
bap = &label;
|
||||
else {
|
||||
if (!bap->isEmpty())
|
||||
bap->append('\n');
|
||||
if (c == 0x1f && split < 0)
|
||||
split = bap->size();
|
||||
}
|
||||
} else if (c < 0x07) {
|
||||
shieldType = static_cast<Shield::Type>(c);
|
||||
bap = &shieldLabel;
|
||||
} else if (bap == &shieldLabel && c == 0x20) {
|
||||
bap = &label;
|
||||
} else
|
||||
bap->append(c);
|
||||
}
|
||||
|
||||
if (split >= 0)
|
||||
label = label.left(split) + ft2m(label.mid(split));
|
||||
else if (convert)
|
||||
label = ft2m(label);
|
||||
QString text(_codec.toString(label));
|
||||
return Label(capitalize && isAllUpperCase(text) ? capitalized(text) : text,
|
||||
Shield(shieldType, _codec.toString(shieldLabel)));
|
||||
}
|
||||
|
||||
Label LBLFile::label8b(Handle &hdl, quint32 offset, bool capitalize,
|
||||
bool convert) const
|
||||
Label LBLFile::label8b(const SubFile *file, Handle &fileHdl, quint32 size,
|
||||
bool capitalize, bool convert) const
|
||||
{
|
||||
QVector<quint8> str;
|
||||
quint8 c;
|
||||
|
||||
if (!seek(hdl, offset))
|
||||
return Label();
|
||||
|
||||
do {
|
||||
if (!readByte(hdl, &c))
|
||||
return Label();
|
||||
for (quint32 i = 0; i < size; i++) {
|
||||
if (!file->readByte(fileHdl, &c))
|
||||
break;
|
||||
str.append(c);
|
||||
} while (c);
|
||||
if (!c)
|
||||
return str2label(str, capitalize, convert);
|
||||
}
|
||||
|
||||
return str2label(str, capitalize, convert);
|
||||
return Label();
|
||||
}
|
||||
|
||||
Label LBLFile::labelHuffman(Handle &hdl, quint32 offset, bool capitalize,
|
||||
bool convert) const
|
||||
Label LBLFile::labelHuffman(Handle &hdl, const SubFile *file, Handle &fileHdl,
|
||||
quint32 size, bool capitalize, bool convert) const
|
||||
{
|
||||
QVector<quint8> str;
|
||||
quint32 end = _offset + _size;
|
||||
|
||||
if (!seek(hdl, offset))
|
||||
return Label();
|
||||
if (!_huffmanText->decode(this, hdl, end - offset, str))
|
||||
if (!_huffmanText->decode(file, fileHdl, size, str))
|
||||
return Label();
|
||||
if (!_table)
|
||||
return str2label(str, capitalize, convert);
|
||||
@ -291,7 +287,7 @@ Label LBLFile::labelHuffman(Handle &hdl, quint32 offset, bool capitalize,
|
||||
else if (str2.size())
|
||||
str2.append(' ');
|
||||
|
||||
if (!_huffmanText->decode(this, hdl, end - off, str2))
|
||||
if (!_huffmanText->decode(this, hdl, _offset + _size - off, str2))
|
||||
return Label();
|
||||
} else {
|
||||
if (str.at(i) == 7) {
|
||||
@ -316,22 +312,31 @@ Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize,
|
||||
if (!(_poiSize >= (offset << _poiMultiplier)
|
||||
&& seek(hdl, _poiOffset + (offset << _poiMultiplier))
|
||||
&& readUInt24(hdl, poiOffset) && (poiOffset & 0x3FFFFF)))
|
||||
return QString();
|
||||
return Label();
|
||||
labelOffset = _offset + ((poiOffset & 0x3FFFFF) << _multiplier);
|
||||
} else
|
||||
labelOffset = _offset + (offset << _multiplier);
|
||||
|
||||
if (labelOffset > _offset + _size)
|
||||
return QString();
|
||||
return Label();
|
||||
if (!seek(hdl, labelOffset))
|
||||
return Label();
|
||||
|
||||
return label(hdl, this, hdl, _offset + _size - labelOffset, capitalize,
|
||||
convert);
|
||||
}
|
||||
|
||||
Label LBLFile::label(Handle &hdl, const SubFile *file, Handle &fileHdl,
|
||||
quint32 size, bool capitalize, bool convert) const
|
||||
{
|
||||
switch (_encoding) {
|
||||
case 6:
|
||||
return label6b(hdl, labelOffset, capitalize, convert);
|
||||
return label6b(file, fileHdl, size, capitalize, convert);
|
||||
case 9:
|
||||
case 10:
|
||||
return label8b(hdl, labelOffset, capitalize, convert);
|
||||
return label8b(file, fileHdl, size, capitalize, convert);
|
||||
case 11:
|
||||
return labelHuffman(hdl, labelOffset, capitalize, convert);
|
||||
return labelHuffman(hdl, file, fileHdl, size, capitalize, convert);
|
||||
default:
|
||||
return Label();
|
||||
}
|
||||
|
@ -33,6 +33,8 @@ public:
|
||||
|
||||
Label label(Handle &hdl, quint32 offset, bool poi = false,
|
||||
bool capitalize = true, bool convert = false) const;
|
||||
Label label(Handle &hdl, const SubFile *file, Handle &fileHdl,
|
||||
quint32 size, bool capitalize = true, bool convert = false) const;
|
||||
|
||||
quint8 imageIdSize() const {return _imgOffsetIdSize;}
|
||||
QPixmap image(Handle &hdl, quint32 id) const;
|
||||
@ -45,12 +47,12 @@ private:
|
||||
|
||||
Label str2label(const QVector<quint8> &str, bool capitalize,
|
||||
bool convert) const;
|
||||
Label label6b(Handle &hdl, quint32 offset, bool capitalize,
|
||||
bool convert) const;
|
||||
Label label8b(Handle &hdl, quint32 offset, bool capitalize,
|
||||
bool convert) const;
|
||||
Label labelHuffman(Handle &hdl, quint32 offset, bool capitalize,
|
||||
bool convert) const;
|
||||
Label label6b(const SubFile *file, Handle &fileHdl, quint32 size,
|
||||
bool capitalize, bool convert) const;
|
||||
Label label8b(const SubFile *file, Handle &fileHdl, quint32 size,
|
||||
bool capitalize, bool convert) const;
|
||||
Label labelHuffman(Handle &hdl, const SubFile *file, Handle &fileHdl,
|
||||
quint32 size, bool capitalize, bool convert) const;
|
||||
bool loadRasterTable(Handle &hdl, quint32 offset, quint32 size,
|
||||
quint32 recordSize);
|
||||
|
||||
|
@ -38,12 +38,13 @@ public:
|
||||
};
|
||||
|
||||
struct Point {
|
||||
Point() : id(0) {}
|
||||
Point() : id(0), classLabel(false) {}
|
||||
|
||||
Coordinates coordinates;
|
||||
Label label;
|
||||
quint32 type;
|
||||
quint64 id;
|
||||
bool classLabel;
|
||||
|
||||
bool operator<(const Point &other) const
|
||||
{return id < other.id;}
|
||||
|
@ -37,7 +37,7 @@ static bool skipShape(BitStream4R &bs)
|
||||
{
|
||||
quint32 v1, v2, v2b;
|
||||
|
||||
if (!bs.readVuint32SM(v1, v2, v2b))
|
||||
if (!bs.readVUint32SM(v1, v2, v2b))
|
||||
return false;
|
||||
|
||||
return bs.skip(v1);
|
||||
@ -64,7 +64,7 @@ static bool seekToLevel(BitStream4R &bs, quint8 level)
|
||||
quint32 v1, v2, v2b;
|
||||
|
||||
for (quint8 i = 1; i < level; ) {
|
||||
if (!bs.readVuint32SM(v1, v2, v2b))
|
||||
if (!bs.readVUint32SM(v1, v2, v2b))
|
||||
return false;
|
||||
if (!bs.skip(v1))
|
||||
return false;
|
||||
@ -83,7 +83,7 @@ static bool seekToLine(BitStream4R &bs, quint8 line)
|
||||
quint32 v1, v2, v2b;
|
||||
|
||||
for (quint8 i = 0; i < line; i++) {
|
||||
if (!bs.readVuint32SM(v1, v2, v2b))
|
||||
if (!bs.readVUint32SM(v1, v2, v2b))
|
||||
return false;
|
||||
if (!bs.skip(v1))
|
||||
return false;
|
||||
@ -99,7 +99,7 @@ static bool readLine(BitStream4R &bs, const SubDiv *subdiv,
|
||||
const HuffmanTable *table, MapData::Poly &poly)
|
||||
{
|
||||
quint32 v1, v2, v2b;
|
||||
if (!bs.readVuint32SM(v1, v2, v2b))
|
||||
if (!bs.readVUint32SM(v1, v2, v2b))
|
||||
return false;
|
||||
bs.resize(v1);
|
||||
|
||||
@ -170,7 +170,7 @@ static bool readShape(const NODFile *nod, SubFile::Handle &nodHdl,
|
||||
quint16 cnt = 0xFFFF, bool check = false)
|
||||
{
|
||||
quint32 v1, v2, v2b;
|
||||
if (!bs.readVuint32SM(v1, v2, v2b))
|
||||
if (!bs.readVUint32SM(v1, v2, v2b))
|
||||
return false;
|
||||
BitStream4R::State state;
|
||||
bs.save(state);
|
||||
@ -298,7 +298,7 @@ static bool readShape(const NODFile *nod, SubFile::Handle &nodHdl,
|
||||
|
||||
if (check && nodes == cnt) {
|
||||
if (!(bs.restore(state) && bs.skip(v1)
|
||||
&& bs.readVuint32SM(v1, v2, v2b)))
|
||||
&& bs.readVUint32SM(v1, v2, v2b)))
|
||||
return false;
|
||||
if (5 < v2b)
|
||||
v2 >>= v2b - 2;
|
||||
|
@ -54,10 +54,16 @@ static QFont *font(Style::FontSize size, Style::FontSize defaultSize
|
||||
}
|
||||
}
|
||||
|
||||
static QFont *poiFont(Style::FontSize size = Style::Normal)
|
||||
static QFont *poiFont(Style::FontSize size = Style::Normal, int zoom = -1,
|
||||
bool extended = false)
|
||||
{
|
||||
static QFont poi = pixelSizeFont(10);
|
||||
|
||||
if (zoom > 25)
|
||||
size = Style::Normal;
|
||||
else if (extended)
|
||||
size = Style::None;
|
||||
|
||||
switch (size) {
|
||||
case Style::None:
|
||||
return 0;
|
||||
@ -435,7 +441,7 @@ void RasterTile::processPoints(QList<TextItem*> &textItems)
|
||||
? 0 : &(point.label.text());
|
||||
const QImage *img = style.img().isNull() ? 0 : &style.img();
|
||||
const QFont *fnt = poi
|
||||
? poiFont(_zoom > 25 ? Style::Normal : style.textFontSize())
|
||||
? poiFont(style.textFontSize(), _zoom, point.classLabel)
|
||||
: font(style.textFontSize());
|
||||
const QColor *color = style.textColor().isValid()
|
||||
? &style.textColor() : &textColor;
|
||||
|
@ -18,7 +18,7 @@ static quint64 pointId(const QPoint &pos, quint32 type, quint32 labelPtr)
|
||||
quint64 id;
|
||||
|
||||
uint hash = (uint)qHash(QPair<uint,uint>((uint)qHash(
|
||||
QPair<int, int>(pos.x(), pos.y())), labelPtr & 0x3FFFFF));
|
||||
QPair<int, int>(pos.x(), pos.y())), labelPtr));
|
||||
id = ((quint64)type)<<32 | hash;
|
||||
// Make country labels precedent over city labels
|
||||
if (!Style::isCountry(type))
|
||||
@ -33,10 +33,14 @@ RGNFile::~RGNFile()
|
||||
}
|
||||
|
||||
bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType,
|
||||
MapData::Poly *poly, const LBLFile *lbl) const
|
||||
void *object, const LBLFile *lbl, Handle &lblHdl) const
|
||||
{
|
||||
quint8 flags;
|
||||
quint32 rs;
|
||||
MapData::Poly *poly = (segmentType == Polygon)
|
||||
? (MapData::Poly *) object : 0;
|
||||
MapData::Point *point = (segmentType == Point)
|
||||
? (MapData::Point *) object : 0;
|
||||
|
||||
if (!readByte(hdl, &flags))
|
||||
return false;
|
||||
@ -60,8 +64,9 @@ bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType,
|
||||
break;
|
||||
}
|
||||
|
||||
if (segmentType == Polygon && Style::isRaster(poly->type) && lbl
|
||||
&& lbl->imageIdSize()) {
|
||||
quint32 off = pos(hdl);
|
||||
|
||||
if (poly && Style::isRaster(poly->type) && lbl && lbl->imageIdSize()) {
|
||||
quint32 id;
|
||||
quint32 top, right, bottom, left;
|
||||
|
||||
@ -74,11 +79,14 @@ bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType,
|
||||
|
||||
poly->raster = Raster(lbl, id, QRect(QPoint(left, top), QPoint(right,
|
||||
bottom)));
|
||||
|
||||
rs -= lbl->imageIdSize() + 16;
|
||||
}
|
||||
|
||||
return seek(hdl, pos(hdl) + rs);
|
||||
if (point && (flags & 1) && lbl) {
|
||||
point->label = lbl->label(lblHdl, this, hdl, rs);
|
||||
point->classLabel = true;
|
||||
}
|
||||
|
||||
return seek(hdl, off + rs);
|
||||
}
|
||||
|
||||
bool RGNFile::skipLclFields(Handle &hdl, const quint32 flags[3]) const
|
||||
@ -345,7 +353,8 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
|
||||
if (subtype & 0x20 && !readUInt24(hdl, labelPtr))
|
||||
return false;
|
||||
if (subtype & 0x80 && !readClassFields(hdl, segmentType, &poly, lbl))
|
||||
if (subtype & 0x80 && !readClassFields(hdl, segmentType, &poly, lbl,
|
||||
lblHdl))
|
||||
return false;
|
||||
if (subtype & 0x40 && !skipLclFields(hdl, segmentType == Line
|
||||
? _linesLclFlags : _polygonsLclFlags))
|
||||
@ -431,26 +440,28 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
&& readInt16(hdl, lon) && readInt16(hdl, lat)))
|
||||
return false;
|
||||
|
||||
point.type = 0x10000 | (((quint32)type)<<8) | (subtype & 0x1F);
|
||||
|
||||
if (subtype & 0x20 && !readUInt24(hdl, labelPtr))
|
||||
return false;
|
||||
if (subtype & 0x80 && !readClassFields(hdl, Point))
|
||||
if (subtype & 0x80 && !readClassFields(hdl, Point, &point, lbl, lblHdl))
|
||||
return false;
|
||||
if (subtype & 0x40 && !skipLclFields(hdl, _pointsLclFlags))
|
||||
return false;
|
||||
if (_pointsGblFlags && !skipGblFields(hdl, _pointsGblFlags))
|
||||
return false;
|
||||
|
||||
QPoint pos(subdiv->lon() + LS(lon, 24-subdiv->bits()),
|
||||
QPoint p(subdiv->lon() + LS(lon, 24-subdiv->bits()),
|
||||
subdiv->lat() + LS(lat, 24-subdiv->bits()));
|
||||
|
||||
point.type = 0x10000 | (((quint32)type)<<8) | (subtype & 0x1F);
|
||||
// Discard NT points breaking style draw order logic (and causing huge
|
||||
// performance drawback)
|
||||
if (point.type == 0x11400)
|
||||
continue;
|
||||
|
||||
point.coordinates = Coordinates(toWGS24(pos.x()), toWGS24(pos.y()));
|
||||
point.id = pointId(pos, point.type, labelPtr & 0x3FFFFF);
|
||||
point.coordinates = Coordinates(toWGS24(p.x()), toWGS24(p.y()));
|
||||
point.id = pointId(p, point.type, point.classLabel ? pos(hdl)
|
||||
: labelPtr & 0x3FFFFF);
|
||||
if (lbl && (labelPtr & 0x3FFFFF))
|
||||
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF);
|
||||
|
||||
|
@ -62,8 +62,8 @@ public:
|
||||
|
||||
private:
|
||||
bool segments(Handle &hdl, SubDiv *subdiv, SubDiv::Segment seg[5]) const;
|
||||
bool readClassFields(Handle &hdl, SegmentType segmentType,
|
||||
MapData::Poly *poly = 0, const LBLFile *lbl = 0) const;
|
||||
bool readClassFields(Handle &hdl, SegmentType segmentType, void *object,
|
||||
const LBLFile *lbl, Handle &lblHdl) const;
|
||||
bool skipLclFields(Handle &hdl, const quint32 flags[3]) const;
|
||||
bool skipGblFields(Handle &hdl, quint32 flags) const;
|
||||
|
||||
|
Reference in New Issue
Block a user