Come implementare lo scorrimento delle pagine del lettore di e-book con dimensioni variabili della pagina?

3

Sono uno studente di CS e per esercitare le mie capacità di codifica sto cercando di implementare un lettore di e-book e desidero qualche consiglio da parte di programmatori più esperti. Sto usando C ++ \ QML ma cercherò di mantenere il mio problema non specifico per qualsiasi tecnologia.

Prefazione piccola

Una volta aperto il libro, lo tengo in memoria. Genero anche una serie di pagine. Inizialmente tengo in memoria:

  • la pagina corrente;
  • 3 pagine a sinistra;
  • 3 pagine a destra.

Le ultime due opzioni sono necessarie per consentire lo scorrimento veloce. Quando l'utente scorre indietro di una pagina \ inoltra il mio programma calcola alcune pagine aggiuntive in quella direzione.

Permetto anche all'utente di cambiare la dimensione della finestra che influisce sulle dimensioni della pagina. E qui ci sono problemi.

Il problema

Ogni volta che l'utente cambia la dimensione della finestra cambia la dimensione della pagina = > il programma deve ricalcolare lo stato della pagina attualmente visualizzata (la sua dimensione e il suo contenuto) e anche le pagine vicine. Ci vuole un po 'di tempo.

Quindi ogni volta che l'utente si diverte con la finestra dell'app, il mio programma ha dei tempi difficili nei calcoli. Quelle calibrazioni richiedono del tempo e rallentano l'intera app.

Cosa ho fatto per risolverlo

  1. Ho pensato di vietare all'utente di modificare manualmente le dimensioni della finestra (e dargli alcune dimensioni di pagina consentite), ma non sono sicuro di quanto sia facile da usare :) In questo caso, potrei calcolare pagine di dimensioni predefinite al iniziando così non rallenterà l'app tanto quanto ora.
  2. Pensavo che il multi-threading mi avrebbe salvato. Da vero principiante all'inizio ho fatto tutto in un thread. Finché la mia app ha iniziato a funzionare davvero (lentamente ovviamente, poiché la mia GUI si bloccava a volte a causa di calcoli), ho introdotto il multi-threading e ora la mia GUI e il thread di lavoro sono separati. È più veloce un po 'ora, ma a volte riesco a vedere quanto è lento, specialmente su un laptop piccolo, quando scorri le pagine più velocemente di una tartaruga.

Quindi, la mia domanda è: quanto è appropriato il mio approccio? È sano di mente e quali sono i modi per migliorare la perfomance?

    
posta Neilana 07.02.2018 - 05:52
fonte

3 risposte

3

È sicuramente una buona idea separare il layout delle pagine dal rendering. Metterli su fili diversi è una buona idea. Non penso però che la soluzione sia di fare un layout speculativo a diverse dimensioni. Penso che finirai per fare un sacco di lavoro inutile. Inoltre, non mi piace l'idea di forzare l'utente a un certo numero di dimensioni.

Quello che farò dopo è profilare la tua applicazione per vedere cosa impiega più tempo durante il layout della pagina. Un profiler ti dirà quale funzione occupa più tempo nella tua applicazione. È quindi possibile esaminare quella funzione per determinare il motivo per cui sta impiegando così tanto tempo. Spesso un'operazione può essere eseguita più velocemente utilizzando un layout di dati diverso, una struttura dati diversa o un algoritmo diverso. Ad esempio, la ricerca del valore massimo in un array richiede il controllo di ogni elemento una volta per vedere se quell'elemento è più grande del massimo corrente. Ma se l'array è già ordinato, richiede solo una lettura dell'ultimo elemento.

Una volta che hai profilato il tuo codice, puoi lavorare per rendere quelle funzioni più veloci o pubblicare più domande qui su modi migliori per affrontare il problema.

    
risposta data 07.02.2018 - 06:51
fonte
1

Considero che il ricalcolo da te menzionato sia il calcolo del flusso del testo, man mano che si mantiene la stessa dimensione del carattere, ma si cambia l'area della pagina?

  1. Devi ottimizzare la logica di rendering / rasterizzazione della pagina per la velocità.
  2. Le pagine adiacenti possono essere mantenute con una qualità / risoluzione inferiore.
  3. Ogni pagina può avere la sua subroutine / attività di rendering, su un thread di lavoro separato (con una coda FIFO e un supporto per la cancellazione) che può essere eseguito separatamente dal cambio di pagina.
  4. La pagina che cambia o ridimensiona semplicemente ridistribuisce il contenuto (inizio / fine) tra le pagine di memoria. Il lavoro di rendering effettivo viene inviato alla coda di lavoro (n. 3).
  5. Pagine che escono dall'ambito, annulla qualsiasi attività di rendering incompleta in coda.
  6. Il thread dei worker preleva le attività più recentemente inviate alla coda FIFO. Cioè: la pagina appena presentata all'utente viene visualizzata per prima.

L'effetto complessivo sarà che l'utente possa passare o ridimensionare quanto più velocemente gli piace, il contenuto verrà visualizzato con un leggero ritardo, non appena l'attività di rendering nella coda di lavoro (n. 3) sarà completata.

    
risposta data 07.02.2018 - 08:03
fonte
-1

Il contenuto di una pagina non dovrebbe cambiare in base alle dimensioni dell'area di visualizzazione. Stai rilevando una complessità inutile perché stai trattando le pagine dei libri come se fossero pagine HTML. Non lo sono.

Pagina 47 di "Treasure Island" dovrebbe essere lo stesso contenuto, indipendentemente dal livello di zoom. La maggior parte dei lettori di e-book onora l'impaginazione del libro stampato originale.

Una volta eliminata la necessità di mescolare i contenuti, il rendering e lo scorrimento delle pagine diventano molto più semplici. Non importa se si utilizza un'opzione di zoom percentuale o un'opzione di dimensioni fisse (piccola, media, grande, ecc.) O si utilizza la dimensione fisica della finestra. Per ciascuna dimensione del display, devi solo decidere il carattere appropriato, adattare il testo in orizzontale e lasciarlo estendere verticalmente con una barra di scorrimento.

    
risposta data 07.02.2018 - 09:04
fonte

Leggi altre domande sui tag