mirror of
https://github.com/crosspoint-reader/crosspoint-reader.git
synced 2026-08-13 14:21:57 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
970b2c6ca1 | ||
|
|
b6ce599b20 | ||
|
|
f54eab2725 | ||
|
|
0d4c9ab91b | ||
|
|
0daa9db243 | ||
|
|
a2f2eea79e | ||
|
|
86a9b9c4a2 | ||
|
|
ba44978ac4 | ||
|
|
555f76da88 | ||
|
|
0a57c0a5a7 | ||
|
|
a09aef0889 | ||
|
|
8626d69f46 | ||
|
|
fc89e57e69 | ||
|
|
487613b082 | ||
|
|
8d5b119644 | ||
|
|
7271c00d35 |
No files matched your search
+34
-10
@@ -122,19 +122,43 @@ A **Wi-Fi signal strength indicator** (dBm) is displayed on-screen during joined
|
||||
|
||||
CrossPoint supports sending books from Calibre using the CrossPoint Reader device plugin.
|
||||
|
||||
1. Install the plugin in Calibre:
|
||||
|
||||
- Head to https://github.com/crosspoint-reader/calibre-plugins/releases to download the latest version of the crosspoint_reader plugin.
|
||||
|
||||
- Download the zip file.
|
||||
|
||||
- Open Calibre → Preferences → Plugins → Load plugin from file → Select the zip file.
|
||||
#### Installing the Plugin in Calibre
|
||||
|
||||
2. On the device: File Transfer -> Calibre Wireless, then join a network.
|
||||
If you don't already have the plugin installed:
|
||||
|
||||
3. Make sure your computer is on the same Wi-Fi network.
|
||||
1. Head to https://github.com/crosspoint-reader/calibre-plugins/releases to download the latest version of the crosspoint_reader plugin.
|
||||
2. Download the zip file.
|
||||
3. Open Calibre → Preferences → Plugins → Load plugin from file → Select the zip file.
|
||||
4. Restart Calibre.
|
||||
|
||||
4. In Calibre, click "Send to device" to transfer books.
|
||||
#### Configuring the CrossPoint Plugin in Calibre
|
||||
1. In Calibre select Preferences.
|
||||
2. In the Preferences dialog select Plugins.
|
||||
3. In Plugins search for "crosspoint".
|
||||
4. Click on "Customize plugin".
|
||||
5. Update the value for "Host" to match the IP for your device.
|
||||
6. Leave the other settings as they are.
|
||||
7. [optional] Modify the "Upload path" to point to a subfolder other than the root "/" folder. Enter this as a path relative to the root folder. Example: `/mybooks`
|
||||
8. Restart Calibre.
|
||||
|
||||
<img width="420" height="385" alt="Image" src="https://github.com/user-attachments/assets/01fc7e33-a9a7-48ba-9e26-2e68d1f9daec" />
|
||||
|
||||
#### Uploading Books
|
||||
|
||||
To upload a book using the CrossPoint plugin in Calibre:
|
||||
|
||||
1. On the device: File Transfer -> Calibre Wireless, then join a network.
|
||||
2. Select one or more books.
|
||||
3. Right-click on that selection.
|
||||
4. Select "Send to Device" > "Send to main memory"
|
||||
|
||||
The CrossPoint plugin will connect to your device, create a folder for the book's author in the root folder (or the folder you configured for the plugin), then copy the book into that folder.
|
||||
|
||||
<img width="783" height="310" alt="Image" src="https://github.com/user-attachments/assets/741b0909-2e1d-4f16-8af0-2c43fbda5ce6" />
|
||||
|
||||
#### Removing a Book
|
||||
|
||||
Books cannot be removed from your device through Calibre. Use the web interface instead.
|
||||
|
||||
### 3.6 Settings
|
||||
|
||||
|
||||
+22
-14
@@ -3,6 +3,7 @@
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace FsHelpers {
|
||||
@@ -36,12 +37,14 @@ std::string decodeUriEscapes(const std::string& path) {
|
||||
}
|
||||
|
||||
std::string normalisePath(const std::string& path) {
|
||||
std::vector<std::string> components;
|
||||
std::string component;
|
||||
std::vector<std::string_view> components;
|
||||
components.reserve(8); // Eight nested folders is more than we might expect
|
||||
|
||||
for (const auto c : path) {
|
||||
if (c == '/') {
|
||||
if (!component.empty()) {
|
||||
size_t start = 0;
|
||||
for (size_t i = 0; i <= path.length(); ++i) {
|
||||
if (i == path.length() || path[i] == '/') {
|
||||
if (i > start) {
|
||||
std::string_view component(path.data() + start, i - start);
|
||||
if (component == "..") {
|
||||
if (!components.empty()) {
|
||||
components.pop_back();
|
||||
@@ -49,23 +52,28 @@ std::string normalisePath(const std::string& path) {
|
||||
} else {
|
||||
components.push_back(component);
|
||||
}
|
||||
component.clear();
|
||||
}
|
||||
} else {
|
||||
component += c;
|
||||
start = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!component.empty()) {
|
||||
components.push_back(component);
|
||||
if (components.empty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
size_t total_len = 0;
|
||||
for (const auto& c : components) {
|
||||
total_len += c.length() + 1;
|
||||
}
|
||||
|
||||
std::string result;
|
||||
for (const auto& c : components) {
|
||||
if (!result.empty()) {
|
||||
result += "/";
|
||||
result.reserve(total_len - 1);
|
||||
|
||||
for (size_t i = 0; i < components.size(); ++i) {
|
||||
if (i > 0) {
|
||||
result += '/';
|
||||
}
|
||||
result += c;
|
||||
result.append(components[i].data(), components[i].length());
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
+185
-15
@@ -661,8 +661,10 @@ void GfxRenderer::drawRoundedRect(const int x, const int y, const int width, con
|
||||
}
|
||||
|
||||
void GfxRenderer::fillRect(const int x, const int y, const int width, const int height, const bool state) const {
|
||||
for (int fillY = y; fillY < y + height; fillY++) {
|
||||
drawLine(x, fillY, x + width - 1, fillY, state);
|
||||
if (state) {
|
||||
fillRectImpl<Color::Black>(x, y, width, height);
|
||||
} else {
|
||||
fillRectImpl<Color::White>(x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -694,26 +696,194 @@ void GfxRenderer::drawPixelDither<Color::DarkGray>(const int x, const int y) con
|
||||
}
|
||||
|
||||
void GfxRenderer::fillRectDither(const int x, const int y, const int width, const int height, Color color) const {
|
||||
if (color == Color::Clear) {
|
||||
} else if (color == Color::Black) {
|
||||
fillRect(x, y, width, height, true);
|
||||
} else if (color == Color::White) {
|
||||
fillRect(x, y, width, height, false);
|
||||
} else if (color == Color::LightGray) {
|
||||
for (int fillY = y; fillY < y + height; fillY++) {
|
||||
for (int fillX = x; fillX < x + width; fillX++) {
|
||||
drawPixelDither<Color::LightGray>(fillX, fillY);
|
||||
switch (color) {
|
||||
case Color::Clear:
|
||||
break;
|
||||
case Color::Black:
|
||||
fillRectImpl<Color::Black>(x, y, width, height);
|
||||
break;
|
||||
case Color::White:
|
||||
fillRectImpl<Color::White>(x, y, width, height);
|
||||
break;
|
||||
case Color::LightGray:
|
||||
fillRectImpl<Color::LightGray>(x, y, width, height);
|
||||
break;
|
||||
case Color::DarkGray:
|
||||
fillRectImpl<Color::DarkGray>(x, y, width, height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template <Color C>
|
||||
void GfxRenderer::fillRectImpl(const int x, const int y, const int width, const int height) const {
|
||||
if constexpr (C == Color::Clear) return;
|
||||
if (width <= 0 || height <= 0) return;
|
||||
if (fontCacheManager_ && fontCacheManager_->isScanning()) return;
|
||||
|
||||
// Clip in logical space.
|
||||
const int screenW = getScreenWidth();
|
||||
const int screenH = getScreenHeight();
|
||||
const int lx0 = std::max(0, x);
|
||||
const int ly0 = std::max(0, y);
|
||||
const int lx1 = std::min(screenW, x + width);
|
||||
const int ly1 = std::min(screenH, y + height);
|
||||
if (lx0 >= lx1 || ly0 >= ly1) return;
|
||||
|
||||
// Rotate the two opposing logical corners into physical-framebuffer space.
|
||||
// The bounding rect in physical space is the rect we need to fill — rotation
|
||||
// is rigid (no shear/stretch) so the bbox of the two corners IS the rect.
|
||||
int paX, paY, pbX, pbY;
|
||||
rotateCoordinates(orientation, lx0, ly0, &paX, &paY, panelWidth, panelHeight);
|
||||
rotateCoordinates(orientation, lx1 - 1, ly1 - 1, &pbX, &pbY, panelWidth, panelHeight);
|
||||
|
||||
const int phyX0 = std::min(paX, pbX);
|
||||
const int phyX1 = std::max(paX, pbX); // inclusive
|
||||
int phyY0 = std::min(paY, pbY);
|
||||
int phyY1 = std::max(paY, pbY);
|
||||
|
||||
// Strip mode: clip Y range to the active band and redirect writes.
|
||||
uint8_t* target = getWriteTarget();
|
||||
const int originY = getWriteOriginY();
|
||||
const int writeRows = getWriteRows();
|
||||
phyY0 = std::max(phyY0, originY);
|
||||
phyY1 = std::min(phyY1, originY + writeRows - 1);
|
||||
if (phyY0 > phyY1) return;
|
||||
|
||||
// Bit/byte layout: MSB-first within a byte, so phyX → bit (7 - (phyX & 7)).
|
||||
// Head and tail masks cover only the in-rect bits of the first/last byte.
|
||||
const int byteStart = phyX0 >> 3;
|
||||
const int byteEnd = phyX1 >> 3; // inclusive
|
||||
const uint8_t headMask = static_cast<uint8_t>(0xFFu >> (phyX0 & 7));
|
||||
const uint8_t tailMask = static_cast<uint8_t>(0xFFu << (7 - (phyX1 & 7)));
|
||||
const int32_t panelStride = static_cast<int32_t>(panelWidthBytes);
|
||||
|
||||
if constexpr (C == Color::Black || C == Color::White) {
|
||||
// Solid fill. Framebuffer: 0 = black, 1 = white.
|
||||
const uint8_t fillByte = (C == Color::Black) ? 0x00u : 0xFFu;
|
||||
for (int py = phyY0; py <= phyY1; ++py) {
|
||||
uint8_t* row = target + static_cast<int32_t>(py - originY) * panelStride;
|
||||
if (byteStart == byteEnd) {
|
||||
const uint8_t mask = headMask & tailMask;
|
||||
if constexpr (C == Color::Black) {
|
||||
row[byteStart] &= static_cast<uint8_t>(~mask);
|
||||
} else {
|
||||
row[byteStart] |= mask;
|
||||
}
|
||||
} else {
|
||||
if constexpr (C == Color::Black) {
|
||||
row[byteStart] &= static_cast<uint8_t>(~headMask);
|
||||
if (byteEnd > byteStart + 1) {
|
||||
memset(row + byteStart + 1, fillByte, byteEnd - byteStart - 1);
|
||||
}
|
||||
row[byteEnd] &= static_cast<uint8_t>(~tailMask);
|
||||
} else {
|
||||
row[byteStart] |= headMask;
|
||||
if (byteEnd > byteStart + 1) {
|
||||
memset(row + byteStart + 1, fillByte, byteEnd - byteStart - 1);
|
||||
}
|
||||
row[byteEnd] |= tailMask;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (color == Color::DarkGray) {
|
||||
for (int fillY = y; fillY < y + height; fillY++) {
|
||||
for (int fillX = x; fillX < x + width; fillX++) {
|
||||
drawPixelDither<Color::DarkGray>(fillX, fillY);
|
||||
} else {
|
||||
// Dither (LightGray / DarkGray). Both patterns have period 2 in logical
|
||||
// (x, y), so per physical row we precompute one byte that represents the
|
||||
// pattern across an 8-pixel stretch — every full byte in the row uses
|
||||
// that same value.
|
||||
//
|
||||
// dlxPerPhyX / dlyPerPhyX: how logical (x, y) change as phyX increments
|
||||
// along a physical row. Derived from inverting rotateCoordinates.
|
||||
int dlxPerPhyX = 0, dlyPerPhyX = 0;
|
||||
switch (orientation) {
|
||||
case Portrait:
|
||||
dlxPerPhyX = 0;
|
||||
dlyPerPhyX = 1;
|
||||
break;
|
||||
case PortraitInverted:
|
||||
dlxPerPhyX = 0;
|
||||
dlyPerPhyX = -1;
|
||||
break;
|
||||
case LandscapeClockwise:
|
||||
dlxPerPhyX = -1;
|
||||
dlyPerPhyX = 0;
|
||||
break;
|
||||
case LandscapeCounterClockwise:
|
||||
dlxPerPhyX = 1;
|
||||
dlyPerPhyX = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// The dither pattern has period 2 in logical space, and each orientation
|
||||
// maps py to logical coords with a fixed parity relationship. The
|
||||
// blackMask byte therefore repeats with period 2 in py. Precompute both
|
||||
// variants outside the row loop to eliminate the per-row switch + 8-bit
|
||||
// construction loop.
|
||||
uint8_t blackMasks[2];
|
||||
for (int parityIdx = 0; parityIdx < 2; ++parityIdx) {
|
||||
const int samplePy = phyY0 + parityIdx;
|
||||
int lxBase = 0, lyBase = 0;
|
||||
switch (orientation) {
|
||||
case Portrait:
|
||||
lxBase = panelHeight - 1 - samplePy;
|
||||
lyBase = byteStart * 8;
|
||||
break;
|
||||
case PortraitInverted:
|
||||
lxBase = samplePy;
|
||||
lyBase = panelWidth - 1 - byteStart * 8;
|
||||
break;
|
||||
case LandscapeClockwise:
|
||||
lxBase = panelWidth - 1 - byteStart * 8;
|
||||
lyBase = panelHeight - 1 - samplePy;
|
||||
break;
|
||||
case LandscapeCounterClockwise:
|
||||
lxBase = byteStart * 8;
|
||||
lyBase = samplePy;
|
||||
break;
|
||||
}
|
||||
uint8_t mask = 0;
|
||||
for (int b = 0; b < 8; ++b) {
|
||||
const int lx = lxBase + b * dlxPerPhyX;
|
||||
const int ly = lyBase + b * dlyPerPhyX;
|
||||
bool isBlack;
|
||||
if constexpr (C == Color::LightGray) {
|
||||
isBlack = ((lx & 1) == 0) && ((ly & 1) == 0);
|
||||
} else { // DarkGray
|
||||
isBlack = (((lx + ly) & 1) == 0);
|
||||
}
|
||||
if (isBlack) mask |= static_cast<uint8_t>(1u << (7 - b));
|
||||
}
|
||||
blackMasks[samplePy & 1] = mask;
|
||||
}
|
||||
|
||||
for (int py = phyY0; py <= phyY1; ++py) {
|
||||
const uint8_t blackMask = blackMasks[py & 1];
|
||||
const uint8_t whiteMask = static_cast<uint8_t>(~blackMask);
|
||||
|
||||
// Dither writes BOTH inks (the slow path called drawPixel for every
|
||||
// pixel — setting or clearing — so we must do the same). Inside the
|
||||
// rect mask: write whiteMask (1s where white, 0s where black). Outside
|
||||
// the rect mask: leave the framebuffer untouched.
|
||||
uint8_t* row = target + static_cast<int32_t>(py - originY) * panelStride;
|
||||
if (byteStart == byteEnd) {
|
||||
const uint8_t rectMask = headMask & tailMask;
|
||||
row[byteStart] = static_cast<uint8_t>((row[byteStart] & ~rectMask) | (rectMask & whiteMask));
|
||||
} else {
|
||||
row[byteStart] = static_cast<uint8_t>((row[byteStart] & ~headMask) | (headMask & whiteMask));
|
||||
if (byteEnd > byteStart + 1) {
|
||||
// Period 2, so every full byte in this row is exactly whiteMask.
|
||||
memset(row + byteStart + 1, whiteMask, byteEnd - byteStart - 1);
|
||||
}
|
||||
row[byteEnd] = static_cast<uint8_t>((row[byteEnd] & ~tailMask) | (tailMask & whiteMask));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template void GfxRenderer::fillRectImpl<Color::Black>(int, int, int, int) const;
|
||||
template void GfxRenderer::fillRectImpl<Color::White>(int, int, int, int) const;
|
||||
template void GfxRenderer::fillRectImpl<Color::LightGray>(int, int, int, int) const;
|
||||
template void GfxRenderer::fillRectImpl<Color::DarkGray>(int, int, int, int) const;
|
||||
|
||||
void GfxRenderer::maskRoundedRectOutsideCorners(const int x, const int y, const int width, const int height,
|
||||
const int radius, const Color color) const {
|
||||
if (radius <= 0 || color == Color::Clear) {
|
||||
|
||||
@@ -81,6 +81,12 @@ class GfxRenderer {
|
||||
void drawPixelDither(int x, int y) const;
|
||||
template <Color color>
|
||||
void fillArc(int maxRadius, int cx, int cy, int xDir, int yDir) const;
|
||||
// Byte-aligned, orientation-specialized rectangle fill. Rotates the rect's
|
||||
// two opposing corners into physical-framebuffer space once, then walks each
|
||||
// physical row with head-mask / middle memset / tail-mask byte writes — no
|
||||
// per-pixel rotation, no per-pixel RMW.
|
||||
template <Color color>
|
||||
void fillRectImpl(int x, int y, int width, int height) const;
|
||||
|
||||
public:
|
||||
explicit GfxRenderer(HalDisplay& halDisplay)
|
||||
|
||||
@@ -126,6 +126,7 @@ STR_PAGE_TURN: "Перагортванне"
|
||||
STR_PORTRAIT: "Партрэт"
|
||||
STR_LANDSCAPE_CW: "Ландшафт (CW)"
|
||||
STR_INVERTED: "Інверсія"
|
||||
STR_ORIENTATION_INVERTED: "Партрэт 180°"
|
||||
STR_LANDSCAPE_CCW: "Ландшафт (CCW)"
|
||||
STR_PREV_NEXT: "Назад/Наперад"
|
||||
STR_NEXT_PREV: "Наперад/Назад"
|
||||
|
||||
@@ -136,6 +136,7 @@ STR_PAGE_TURN: "Canvi de pàgina"
|
||||
STR_PORTRAIT: "Vertical"
|
||||
STR_LANDSCAPE_CW: "Horitzontal horari"
|
||||
STR_INVERTED: "Invertit"
|
||||
STR_ORIENTATION_INVERTED: "Vertical 180°"
|
||||
STR_LANDSCAPE_CCW: "Horitzontal antihorari"
|
||||
STR_PREV_NEXT: "Anterior/Següent"
|
||||
STR_NEXT_PREV: "Següent/Anterior"
|
||||
|
||||
@@ -131,6 +131,7 @@ STR_PAGE_TURN: "Otáčení stránek"
|
||||
STR_PORTRAIT: "Na výšku"
|
||||
STR_LANDSCAPE_CW: "Na šířku po směru hod. ručiček"
|
||||
STR_INVERTED: "Invertovaný"
|
||||
STR_ORIENTATION_INVERTED: "Na výšku 180°"
|
||||
STR_LANDSCAPE_CCW: "Na šířku proti směru hod. ručiček"
|
||||
STR_PREV_NEXT: "Předchozí/Další"
|
||||
STR_NEXT_PREV: "Další/Předchozí"
|
||||
|
||||
@@ -136,6 +136,7 @@ STR_PAGE_TURN: "Sideskift"
|
||||
STR_PORTRAIT: "Portræt"
|
||||
STR_LANDSCAPE_CW: "Liggende med uret"
|
||||
STR_INVERTED: "Inverteret"
|
||||
STR_ORIENTATION_INVERTED: "Portræt 180°"
|
||||
STR_LANDSCAPE_CCW: "Liggende mod uret"
|
||||
STR_PREV_NEXT: "Forrige/Næste"
|
||||
STR_NEXT_PREV: "Næste/Forrige"
|
||||
|
||||
@@ -135,7 +135,8 @@ STR_SLEEP: "Slaap"
|
||||
STR_PAGE_TURN: "Pagina omslaan"
|
||||
STR_PORTRAIT: "Staand"
|
||||
STR_LANDSCAPE_CW: "Liggend (rechtsom)"
|
||||
STR_INVERTED: "Omgekeerd"
|
||||
STR_INVERTED: "Geïnverteerd"
|
||||
STR_ORIENTATION_INVERTED: "Staand 180°"
|
||||
STR_LANDSCAPE_CCW: "Liggend (linksom)"
|
||||
STR_PREV_NEXT: "Vorige/Volgende"
|
||||
STR_NEXT_PREV: "Volgende/Vorige"
|
||||
|
||||
@@ -139,6 +139,7 @@ STR_FORCE_REFRESH: "Refresh Screen"
|
||||
STR_PORTRAIT: "Portrait"
|
||||
STR_LANDSCAPE_CW: "Landscape CW"
|
||||
STR_INVERTED: "Inverted"
|
||||
STR_ORIENTATION_INVERTED: "Portrait 180°"
|
||||
STR_LANDSCAPE_CCW: "Landscape CCW"
|
||||
STR_PREV_NEXT: "Prev/Next"
|
||||
STR_NEXT_PREV: "Next/Prev"
|
||||
|
||||
@@ -130,7 +130,8 @@ STR_SLEEP: "Lepotila"
|
||||
STR_PAGE_TURN: "Sivunkääntö"
|
||||
STR_PORTRAIT: "Pysty"
|
||||
STR_LANDSCAPE_CW: "Vaaka myötäpäivään"
|
||||
STR_INVERTED: "Käännetty"
|
||||
STR_INVERTED: "Käänteinen"
|
||||
STR_ORIENTATION_INVERTED: "Pysty 180°"
|
||||
STR_LANDSCAPE_CCW: "Vaaka vastapäivään"
|
||||
STR_PREV_NEXT: "Edell/Seur"
|
||||
STR_NEXT_PREV: "Seur/Edell"
|
||||
|
||||
@@ -136,6 +136,7 @@ STR_PAGE_TURN: "Page suivante"
|
||||
STR_PORTRAIT: "Portrait"
|
||||
STR_LANDSCAPE_CW: "Paysage"
|
||||
STR_INVERTED: "Inversé"
|
||||
STR_ORIENTATION_INVERTED: "Portrait 180°"
|
||||
STR_LANDSCAPE_CCW: "Paysage inversé"
|
||||
STR_PREV_NEXT: "Préc/Suiv"
|
||||
STR_NEXT_PREV: "Suiv/Préc"
|
||||
|
||||
@@ -70,7 +70,7 @@ STR_ORIENTATION: "Leseausrichtung"
|
||||
STR_SIDE_BTN_LAYOUT: "Seitliche Tasten (Lesen)"
|
||||
STR_FRONT_BTN_FOLLOW_ORIENTATION: "Vordere Tasten ausrichten"
|
||||
STR_LONG_PRESS_BEHAVIOR: "Verhalten bei langem Tastendruck"
|
||||
STR_LONG_PRESS_BEHAVIOR_OFF: "AUS"
|
||||
STR_LONG_PRESS_BEHAVIOR_OFF: "Aus"
|
||||
STR_LONG_PRESS_BEHAVIOR_SKIP: "Kapitel überspringen"
|
||||
STR_LONG_PRESS_BEHAVIOR_ORIENTATION: "Ausrichtung ändern"
|
||||
STR_FONT_PREVIEW_TEXT: "Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich"
|
||||
@@ -79,8 +79,9 @@ STR_FONT_SIZE: "Schriftgröße"
|
||||
STR_LINE_SPACING: "Lese-Zeilenabstand"
|
||||
STR_SCREEN_MARGIN: "Lese-Seitenränder"
|
||||
STR_PARA_ALIGNMENT: "Lese-Absatzausrichtung"
|
||||
STR_LONG_PRESS_MENU: "Menütaste lang drücken"
|
||||
STR_HYPHENATION: "Silbentrennung"
|
||||
STR_TIME_TO_SLEEP: "Standby nach"
|
||||
STR_TIME_TO_SLEEP: "Standby-Modus nach"
|
||||
STR_REFRESH_FREQ: "Anti-Ghosting nach"
|
||||
STR_KOREADER_SYNC: "KOReader-Synchr."
|
||||
STR_CHECK_UPDATES: "Nach Updates suchen"
|
||||
@@ -129,7 +130,8 @@ STR_PAGE_TURN: "Umblättern"
|
||||
STR_FORCE_REFRESH: "Bildschirm regenerieren"
|
||||
STR_PORTRAIT: "Hochformat"
|
||||
STR_LANDSCAPE_CW: "Querformat rechts"
|
||||
STR_INVERTED: "Hochformat 180°"
|
||||
STR_INVERTED: "Invertiert"
|
||||
STR_ORIENTATION_INVERTED: "Hochformat 180°"
|
||||
STR_LANDSCAPE_CCW: "Querformat links"
|
||||
STR_PREV_NEXT: "Zurück/Weiter"
|
||||
STR_NEXT_PREV: "Weiter/Zurück"
|
||||
|
||||
@@ -134,7 +134,8 @@ STR_PAGE_TURN: "העברת דף"
|
||||
STR_FORCE_REFRESH: "רענון מסך מלא"
|
||||
STR_PORTRAIT: "לאורך"
|
||||
STR_LANDSCAPE_CW: "לרוחב (ימינה)"
|
||||
STR_INVERTED: "הפוך"
|
||||
STR_INVERTED: "היפוך צבעים"
|
||||
STR_ORIENTATION_INVERTED: "לאורך 180°"
|
||||
STR_LANDSCAPE_CCW: "לרוחב (שמאלה)"
|
||||
STR_PREV_NEXT: "הקודם/הבא"
|
||||
STR_NEXT_PREV: "הבא/הקודם"
|
||||
|
||||
@@ -132,7 +132,8 @@ STR_SLEEP: "Alvás"
|
||||
STR_PAGE_TURN: "Lapozás"
|
||||
STR_PORTRAIT: "Álló"
|
||||
STR_LANDSCAPE_CW: "Fekvő jobbra"
|
||||
STR_INVERTED: "Fordított"
|
||||
STR_INVERTED: "Invertált"
|
||||
STR_ORIENTATION_INVERTED: "Álló 180°"
|
||||
STR_LANDSCAPE_CCW: "Fekvő balra"
|
||||
STR_PREV_NEXT: "Előző/Következő"
|
||||
STR_NEXT_PREV: "Következő/Előző"
|
||||
|
||||
@@ -137,7 +137,8 @@ STR_PAGE_TURN: "Cambio pagina"
|
||||
STR_FORCE_REFRESH: "Refresh"
|
||||
STR_PORTRAIT: "Verticale"
|
||||
STR_LANDSCAPE_CW: "Orizzontale Dx"
|
||||
STR_INVERTED: "Capovolto"
|
||||
STR_INVERTED: "Invertito"
|
||||
STR_ORIENTATION_INVERTED: "Verticale 180°"
|
||||
STR_LANDSCAPE_CCW: "Orizzontale Sx"
|
||||
STR_PREV_NEXT: "Prec/Succ"
|
||||
STR_NEXT_PREV: "Succ/Prec"
|
||||
|
||||
@@ -126,7 +126,8 @@ STR_SLEEP: "Ұйқы"
|
||||
STR_PAGE_TURN: "Бет аудару"
|
||||
STR_PORTRAIT: "Тік бағдар"
|
||||
STR_LANDSCAPE_CW: "Көлденең (сағат бағытымен)"
|
||||
STR_INVERTED: "Төңкерілген"
|
||||
STR_INVERTED: "Инверсия"
|
||||
STR_ORIENTATION_INVERTED: "Тік бағдар 180°"
|
||||
STR_LANDSCAPE_CCW: "Көлденең (сағат тіліне қарсы)"
|
||||
STR_PREV_NEXT: "Алдыңғы/Келесі"
|
||||
STR_NEXT_PREV: "Келесі/Алдыңғы"
|
||||
|
||||
@@ -132,7 +132,8 @@ STR_SLEEP: "Miegas"
|
||||
STR_PAGE_TURN: "Versti psl."
|
||||
STR_PORTRAIT: "Stačias"
|
||||
STR_LANDSCAPE_CW: "Gulsčias (P)"
|
||||
STR_INVERTED: "Apverstas"
|
||||
STR_INVERTED: "Invertuotas"
|
||||
STR_ORIENTATION_INVERTED: "Stačias 180°"
|
||||
STR_LANDSCAPE_CCW: "Gulsčias (A)"
|
||||
STR_PREV_NEXT: "Atgal/Pirmyn"
|
||||
STR_NEXT_PREV: "Pirmyn/Atgal"
|
||||
|
||||
@@ -136,7 +136,8 @@ STR_PAGE_TURN: "Nast. str."
|
||||
STR_FORCE_REFRESH: "Odśwież ekran"
|
||||
STR_PORTRAIT: "Pionowo"
|
||||
STR_LANDSCAPE_CW: "Poziomo P"
|
||||
STR_INVERTED: "Odwrócony"
|
||||
STR_INVERTED: "Inwersja"
|
||||
STR_ORIENTATION_INVERTED: "Pionowo 180°"
|
||||
STR_LANDSCAPE_CCW: "Poziomo L"
|
||||
STR_PREV_NEXT: "Poprz./Nast."
|
||||
STR_NEXT_PREV: "Nast./Poprz."
|
||||
|
||||
@@ -131,6 +131,7 @@ STR_PAGE_TURN: "Virar página"
|
||||
STR_PORTRAIT: "Retrato"
|
||||
STR_LANDSCAPE_CW: "Paisagem H"
|
||||
STR_INVERTED: "Invertido"
|
||||
STR_ORIENTATION_INVERTED: "Retrato 180°"
|
||||
STR_LANDSCAPE_CCW: "Paisagem AH"
|
||||
STR_PREV_NEXT: "Ant/Próx"
|
||||
STR_NEXT_PREV: "Próx/Ant"
|
||||
|
||||
Loaded 20 of 40 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user